package com.sinosoft.dsp.system.to;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.w3c.dom.Node;

import com.sinosoft.dsp.system.core.exception.SinoException;
import com.sinosoft.dsp.system.to.attribute.Attribute;
import com.sinosoft.dsp.system.to.exception.SinoAttributeException;
import com.sinosoft.dsp.system.to.exception.SinoAttributeValidationException;
import com.sinosoft.dsp.system.utils.Const;

/**
 * 通用TO实现类
 * 
 * @since 1.0 2010-4-22
 * @author 潘巍（Peter Pan）
 * 
 */
public class GenericTO implements IGenericTO {
	private List<Attribute<?>> attributes = new ArrayList<Attribute<?>>();
	private Map<String, List<IGenericTO>> relations = new HashMap<String, List<IGenericTO>>();

	@Override
	public IBaseTO validate() throws SinoAttributeValidationException {
		// 验证属性
		for (Attribute<?> attr : attributes) {
			attr.validate();
		}

		// 验证关联TO集合
		for (List<IGenericTO> rela : relations.values()) {
			for (IGenericTO to : rela) {
				to.validate();
			}
		}

		return this;
	}

	@Override
	public int getNumberOfAttributes() {
		return this.attributes.size();
	}

	@Override
	public int getNumberOfRelations() {
		return this.relations.size();
	}

	@Override
	public IBaseTO cloneTO() throws SinoAttributeException {
		GenericTO to = new GenericTO();

		// 克隆属性
		for (Attribute<?> attr : attributes) {
			to.getAttributes().add(attr.cloneAttribute());
		}

		// 克隆关联TO
		for (Map.Entry<String, List<IGenericTO>> rela : relations.entrySet()) {
			List<IGenericTO> newTo = new ArrayList<IGenericTO>();
			for (IGenericTO subto : rela.getValue()) {
				newTo.add((IGenericTO) subto.cloneTO());
			}
			to.getRelationsMap().put(rela.getKey(), newTo);
		}
		return to;
	}

	@Override
	public void addRelation(String relationName, IGenericTO genericTO) {
		if (!Const.isEmpty(relationName)) {
			if (!relations.containsKey(relationName)) {
				relations.put(relationName, new ArrayList<IGenericTO>());
			}
			List<IGenericTO> rList = relations.get(relationName);
			rList.add(genericTO);
		}
	}

	@Override
	public Set<String> getRelationNames() {
		return relations.keySet();
	}

	@Override
	public List<IGenericTO> getRelations(String name) {
		return relations.get(name);
	}

	@Override
	public Map<String, List<IGenericTO>> getRelationsMap() {
		return relations;
	}

	@Override
	public List<IGenericTO> removeRelation(String name) {
		return relations.remove(name);
	}

	@Override
	public IBaseTO add(Attribute<?> attribute) {
		if (attribute != null)
			attributes.add(attribute);
		return this;
	}

	@Override
	public Attribute<?>[] cloneAttributes() throws SinoAttributeException {
		Attribute<?>[] attrs = new Attribute<?>[attributes.size()];
		for (int i = 0; i < attributes.size(); i++) {
			attrs[i] = attributes.get(i).cloneAttribute();
		}
		return attrs;
	}

	@Override
	public int compare(Attribute<?>[] attr, int[] attrnrs)
			throws SinoAttributeException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean equals(Attribute<?>[] attr, int[] attrnrs)
			throws SinoAttributeException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean exists(Attribute<?> meta) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Attribute<?> getAttributeByIndex(int index) {
		return attributes.get(index);
	}

	@Override
	public List<String> getAttributeNames() {
		List<String> names = new ArrayList<String>();
		for (Attribute<?> attr : attributes) {
			names.add(attr.getName());
		}
		return names;
	}

	@Override
	public List<Attribute<?>> getAttributes() {
		return attributes;
	}

	@Override
	public IBaseTO getByNode(Node node) throws SinoException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getMetaXML() throws IOException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Attribute<?> remove(String name) {
		for (Attribute<?> attr : attributes) {
			if (attr.getName().equals(name)) {
				attributes.remove(attr);
				return attr;
			}
		}
		return null;
	}

	@Override
	public int indexOf(String name) {
		for (int i = 0; i < getNumberOfAttributes(); i++) {
			if (attributes.get(i).getName().equals(name)) {
				return i;
			}
		}
		return -1;
	}

	@Override
	public Attribute<?> remove(int index) {
		return attributes.remove(index);
	}

	@Override
	public IBaseTO set(int index, Attribute<?> attribute)
			throws SinoAttributeException {
		if (0 <= index && index < attributes.size()) {
			attributes.set(index, attribute);
		} else {
			throw new SinoAttributeException("插入属性[" + attribute.getName()
					+ "]时，发生数组越界！");
		}
		return this;
	}

	@Override
	public String toStringMeta() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Attribute<?> getAttributeByName(String name) {
		int index = indexOf(name);
		if (index > -1) {
			return getAttributeByIndex(index);
		}
		return null;
	}

}
